#!/bin/bash

# TCP网络带宽测试工具 - bond网络专用测试脚本

echo "TCP网络带宽测试工具 - bond网络聚合带宽测试"
echo "=========================================="

# 检查程序是否已编译
if [ ! -f "./tcp_server" ] || [ ! -f "./tcp_client_bond" ]; then
    echo "错误: 程序未编译，请先运行 'make' 编译程序"
    exit 1
fi

# 检查端口是否被占用
check_port() {
    local port=$1
    if netstat -tuln 2>/dev/null | grep -q ":$port "; then
        echo "警告: 端口 $port 已被占用"
        return 1
    fi
    return 0
}

# 启动多线程服务器
start_server() {
    local port=${1:-8888}
    echo "启动多线程服务器，端口: $port"
    ./tcp_server -p $port &
    SERVER_PID=$!
    sleep 3
    
    # 检查服务器是否启动成功
    if ! kill -0 $SERVER_PID 2>/dev/null; then
        echo "错误: 服务器启动失败"
        exit 1
    fi
    echo "多线程服务器启动成功 (PID: $SERVER_PID)"
}

# 停止服务器
stop_server() {
    if [ ! -z "$SERVER_PID" ]; then
        echo "停止服务器 (PID: $SERVER_PID)"
        kill $SERVER_PID 2>/dev/null
        wait $SERVER_PID 2>/dev/null
    fi
}

# 清理函数
cleanup() {
    echo ""
    echo "清理资源..."
    stop_server
    exit 0
}

# 设置信号处理
trap cleanup SIGINT SIGTERM

# 显示bond网络信息
show_bond_info() {
    echo "=== bond网络信息 ==="
    
    # 检查bond接口
    if [ -d "/proc/net/bonding" ]; then
        echo "发现的bond接口:"
        for bond in /proc/net/bonding/*; do
            if [ -f "$bond" ]; then
                bond_name=$(basename "$bond")
                echo "  - $bond_name"
                
                # 显示bond模式
                mode=$(grep "Bonding Mode" "$bond" 2>/dev/null | cut -d: -f2 | tr -d ' ')
                echo "    模式: $mode"
                
                # 显示从属接口
                slaves=$(grep "Slave Interface" "$bond" 2>/dev/null | wc -l)
                echo "    从属接口数: $slaves"
                
                # 显示活跃接口
                active=$(grep "Currently Active Slave" "$bond" 2>/dev/null | cut -d: -f2 | tr -d ' ')
                if [ ! -z "$active" ]; then
                    echo "    当前活跃接口: $active"
                fi
            fi
        done
    else
        echo "未发现bond接口"
    fi
    
    echo ""
    
    # 显示网络接口信息
    echo "网络接口信息:"
    ip addr show | grep -E "^[0-9]+:|inet " | while read line; do
        if [[ $line =~ ^[0-9]+: ]]; then
            interface=$(echo $line | cut -d: -f2 | cut -d@ -f1 | tr -d ' ')
            echo "  $interface"
        elif [[ $line =~ inet ]]; then
            ip=$(echo $line | awk '{print $2}' | cut -d/ -f1)
            echo "    IP: $ip"
        fi
    done
    
    echo "=================="
    echo ""
}

# 主测试函数
run_bond_test() {
    local server_ip=${1:-"127.0.0.1"}
    local port=${2:-8888}
    local data_size=${3:-100}
    local num_threads=${4:-8}
    local bond_interface=${5:-""}
    local use_multi_ip=${6:-1}
    
    echo "开始bond网络聚合带宽测试..."
    echo "服务器: $server_ip:$port"
    echo "总数据大小: ${data_size}MB"
    echo "并发连接数: $num_threads"
    if [ ! -z "$bond_interface" ]; then
        echo "指定bond接口: $bond_interface"
    fi
    if [ $use_multi_ip -eq 1 ]; then
        echo "多IP绑定模式: 启用"
    fi
    echo ""
    
    # 启动服务器
    start_server $port
    
    # 构建客户端命令
    client_cmd="./tcp_client_bond -s $server_ip -p $port -d $data_size -n $num_threads"
    
    if [ ! -z "$bond_interface" ]; then
        client_cmd="$client_cmd -i $bond_interface"
    fi
    
    if [ $use_multi_ip -eq 1 ]; then
        client_cmd="$client_cmd -m"
    fi
    
    # 运行bond网络客户端测试
    echo "运行bond网络客户端测试..."
    echo "命令: $client_cmd"
    echo ""
    
    eval $client_cmd
    
    # 停止服务器
    stop_server
}

# 显示帮助信息
show_help() {
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -s <IP>       服务器IP地址 (默认: 127.0.0.1)"
    echo "  -p <端口>     服务器端口 (默认: 8888)"
    echo "  -d <大小>     测试数据大小MB (默认: 100)"
    echo "  -n <线程数>   并发连接数 (默认: 8)"
    echo "  -b <bond接口> 指定bond接口 (如: bond0)"
    echo "  -i            显示bond网络信息"
    echo "  -h            显示此帮助信息"
    echo ""
    echo "示例:"
    echo "  $0                           # 基本bond测试"
    echo "  $0 -d 1000 -n 16            # 16线程测试1GB"
    echo "  $0 -s 192.168.1.100 -b bond0 # 指定bond接口"
    echo "  $0 -i                        # 显示bond网络信息"
    echo ""
    echo "bond网络测试建议:"
    echo "  - 2网卡bond: 使用8-16个并发连接"
    echo "  - 4网卡bond: 使用16-32个并发连接"
    echo "  - 8网卡bond: 使用32-64个并发连接"
}

# 解析命令行参数
SERVER_IP="127.0.0.1"
PORT=8888
DATA_SIZE=100
NUM_THREADS=8
BOND_INTERFACE=""
SHOW_INFO=0

while getopts "s:p:d:n:b:ih" opt; do
    case $opt in
        s) SERVER_IP="$OPTARG" ;;
        p) PORT="$OPTARG" ;;
        d) DATA_SIZE="$OPTARG" ;;
        n) NUM_THREADS="$OPTARG" ;;
        b) BOND_INTERFACE="$OPTARG" ;;
        i) SHOW_INFO=1 ;;
        h) show_help; exit 0 ;;
        *) show_help; exit 1 ;;
    esac
done

# 如果只是显示信息，显示后退出
if [ $SHOW_INFO -eq 1 ]; then
    show_bond_info
    exit 0
fi

# 验证参数
if [ $PORT -lt 1 ] || [ $PORT -gt 65535 ]; then
    echo "错误: 端口号必须在1-65535之间"
    exit 1
fi

if [ $DATA_SIZE -lt 1 ]; then
    echo "错误: 数据大小必须大于0"
    exit 1
fi

if [ $NUM_THREADS -lt 1 ] || [ $NUM_THREADS -gt 64 ]; then
    echo "错误: 线程数必须在1-64之间"
    exit 1
fi

# 显示bond网络信息
show_bond_info

# 运行测试
run_bond_test $SERVER_IP $PORT $DATA_SIZE $NUM_THREADS "$BOND_INTERFACE" 1

echo "bond网络聚合带宽测试完成！"
